#!/usr/bin/python
#
# Copyright (c) 2009 Julius Volz
# See LICENSE for details.

from optparse import OptionParser
import sys
import config, debug, silk


def run():
  # Parse command line options
  parser = OptionParser(usage='Usage: %prog <config file> [options]\n\n'
                              'Use "%prog --help" to get a detailed usage explanation',
                        version='Silk %s' % silk.version)
  parser.add_option('-l', '--interlink', action='append', dest='linkspecs',
                    help='specify linkspec ID to be executed')
  parser.add_option('-v', '--verbose', action='count', dest='verbosity',
                    default=0, help='verbosity level')
  parser.add_option('-s', '--serve', action='store_true', dest='serve',
                    default=False, help='don\'t run Interlink sections, serve web '
                    'interface instead')
  parser.add_option('-c', '--crawl_uri', action='store', dest='crawl_uri',
                    help='supply resource URI to crawl and find a target resource for')
  parser.add_option('--sync', action='store_true', dest='sync', default=False,
                    help='start link and change synchronization daemon')
  parser.add_option('--no-recompute', action='store_true', dest='no_recompute',
                    default=False, help='when running synchronization daemon, '
                    'do not recompute links before')
  (options, args) = parser.parse_args()

  config.verbosity = options.verbosity
  linkspecs = options.linkspecs

  if options.sync:
    if options.serve:
      parser.error('cannot combine --serve and --sync options')
    if options.crawl_uri is not None:
      parser.error('cannot combine --crawl_uri and --sync options')

  if options.no_recompute and not options.sync:
    parser.error('cannot use --no-recompute without --sync option')

  if options.serve:
    if options.crawl_uri is not None:
      parser.error('cannot combine --serve and --crawl_uri options')
    if linkspecs is not None:
      parser.error('cannot combine --serve and --interlink options')

  # Check whether config file was specified
  #if len(args) != 1:
    # When using web interface, config may be loaded through UI later
  #  if not options.serve:
  #    parser.error('exactly one config file must be specified')
  #else:
    # Load configuration file
  config_file = args[0]
  try:
    config.load(config_file, options.crawl_uri)
  except silk.Error, msg:
    print 'Config error: %s' % msg
    sys.exit(2)

  # Check whether command line linkspec arguments are defined
  if linkspecs is not None:
    for id in linkspecs:
      if id not in config.linkspecs:
        print 'LinkSpec "%s" not defined!' % id
        sys.exit(2)
  else:
    linkspecs = config.linkspecs

  # Run linkspecs
  try:

    # start web interface
    if options.serve:
      from web import web
      web.serve()
    # crawl URI and find target resource
    elif options.crawl_uri:
      for id in linkspecs:
        matches = config.linkspecs[id].find_matches(options.crawl_uri).values()[0]
        for match in matches:
          print '%s\t%s\t%s' % (id, match['similarity'], match['dst'])
    # DEFAULT: run linkspecs and write links to file
    else:
      if options.sync:
        from sync.source import sync
        sync.init()

      if not options.no_recompute:
        if options.sync:
          sync.flush_links(linkspecs)

        for id in linkspecs:
          debug.log(1, 'Running Interlink "%s"...\n' % id)
          config.linkspecs[id].run(sync_daemon=options.sync)
          debug.log(1, 'Done.')

      if options.sync:
        debug.log(1, 'Starting change/link synchronization daemon...')
        sync.run_daemon(transfer=(not options.no_recompute))

  except KeyboardInterrupt:
    debug.log(0, '\nCaught KeyboardInterrupt, shutting down...\n')
  finally:
    for ds in config.datasources.values():
      if ds.do_cache:
        ds.write_cache_to_disk()
